//
//  LRJ_BaseAsyncDrawView.m
//  FBSnapshotTestCase
//
//  Created by imac_LRJ on 2022/6/6.
//

#import "LRJ_BaseAsyncDrawView.h"

//定义key值，用于userinfo的key ，private


NSString * const LRJ_RadiusKey      = @"LRJ_RadiusKey";
NSString * const LRJ_BorderWidthKey       = @"LRJ_BorderWidthKey";
NSString * const LRJ_BorderColorKey       = @"LRJ_BorderColorKey";

NSString * const LRJ_ShadowColorKey       = @"LRJ_ShadowColorKey";
NSString * const LRJ_ShadowOffsetKey      = @"LRJ_ShadowOffsetKey";
NSString * const LRJ_ShadowBlurKey        = @"LRJ_ShadowBlurKey";

NSString * const LRJ_wBackgroundColorKey   = @"LRJ_wBackgroundColorKey";
NSString * const LRJ_BackgroundImageKey   = @"LRJ_BackgroundImageKey";



@interface LRJ_BaseAsyncDrawView()
@property (nonatomic, strong) UIColor *fillColor;

@end


@implementation LRJ_BaseAsyncDrawView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.drawingPolicy = LRJViewDrawingPolicyAsynchronouslyDrawWhenContentsChanged;
        self.backgroundColor = [UIColor clearColor];
        //在诸如drawrect开始前 不清空内容 如果为yes 则图形缓冲区将自动清除为透明黑色，为了提高性能设为NO，因为绘制由我们自己优化
        self.clearsContextBeforeDrawing = NO;
        //立即开始重绘，当bounds改变的时候
        self.contentMode = UIViewContentModeRedraw;
        
        _cornerRadius = 0.0;
        _borderWidth = 0.0;
        _borderColor = nil;
        
        _shadowColor = nil;
        _shadowOffset = UIOffsetZero;
        _shadowBlur = 0.0;
    }
    return self;
}

#pragma mark --- setter & getter 一种优化，防止无意义的重复绘制

- (void)setBackgroundColor:(UIColor *)backgroundColor
{
    if (_fillColor != backgroundColor) {
        _fillColor = backgroundColor;
        self.contentsChangedAfterLastAsyncDrawing = YES;
        [self setNeedsDisplay];
    }
}

- (UIColor *)backgroundColor{
    return _fillColor;
}

- (void)setBackgroundImage:(UIImage *)backgroundImage
{
    if (_backgroundImage != backgroundImage) {
        _backgroundImage = backgroundImage;
        
        self.contentsChangedAfterLastAsyncDrawing = YES;
        [self setNeedsDisplay];
    }
}
//之所以这样写是为了一步到位，防止无效的多次重复设置渲染，降低内存消耗，多次设置，一次渲染
- (NSDictionary *)currentDrawingUserInfo
{
    NSDictionary *dic = [super currentDrawingUserInfo];
    
    NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
    if (dic) {
        [userInfo addEntriesFromDictionary:dic];
    }
    
    if (self.borderWidth > 0.0) {
        [userInfo setValue:@(self.borderWidth) forKey:LRJ_BorderWidthKey];
    }
    
    if (self.cornerRadius >= 0.0) {
        [userInfo setValue:@(self.cornerRadius) forKey:LRJ_RadiusKey];
    }
    
    if (self.borderColor) {
        [userInfo setValue:self.borderColor forKey:LRJ_BorderColorKey];
    }
    
    if (self.shadowColor) {
        [userInfo setValue:self.shadowColor forKey:LRJ_ShadowColorKey];
    }
    
    if (!UIOffsetEqualToOffset(self.shadowOffset, UIOffsetZero)) {
        [userInfo setValue:[NSValue valueWithUIOffset:self.shadowOffset] forKey:LRJ_ShadowOffsetKey];
    }
    
    if (self.shadowBlur > 0.0) {
        [userInfo setValue:@(self.shadowBlur) forKey:LRJ_ShadowBlurKey];
    }
    
    if (self.fillColor) {
        [userInfo setValue:self.fillColor forKey:LRJ_wBackgroundColorKey];
    }
    
    if (self.backgroundImage) {
        [userInfo setValue:self.backgroundImage forKey:LRJ_BackgroundImageKey];
    }
    
    return userInfo;
}


- (BOOL)drawInRect:(CGRect)rect withContext:(CGContextRef)context asynchronously:(BOOL)asynchronously userInfo:(NSDictionary *)userInfo
{
    [super drawInRect:rect withContext:context asynchronously:asynchronously userInfo:userInfo];
    
    UIColor *backgroundColor = (UIColor *)[userInfo valueForKey:LRJ_wBackgroundColorKey];
    
    CGFloat borderWidth = [[userInfo valueForKey:LRJ_BorderWidthKey] floatValue];
    CGFloat cornerRadius = [[userInfo valueForKey:LRJ_RadiusKey] floatValue];
    UIColor *borderColor = (UIColor *)[userInfo valueForKey:LRJ_BorderColorKey];
    
    borderWidth *= [[UIScreen mainScreen] scale];
    
    if(cornerRadius == 0){
        
        if (backgroundColor && backgroundColor != [UIColor clearColor]) {
            CGContextSetFillColorWithColor(context, backgroundColor.CGColor);
            CGContextFillRect(context, rect);
        }
        
        if(borderWidth > 0){
            CGContextAddPath(context, [UIBezierPath bezierPathWithRect:rect].CGPath);
        }
        
        CGContextSetFillColorWithColor(context, [UIColor clearColor].CGColor);
        
        if(borderWidth > 0){
            CGContextSetStrokeColorWithColor(context, borderColor.CGColor);
            CGContextSetLineWidth(context, borderWidth);
            CGContextDrawPath(context, kCGPathFillStroke);
        }else{
            CGContextDrawPath(context, kCGPathFill);
        }
    }
    else{
        
        CGRect targetRect = CGRectMake(0, 0, rect.size.width , rect.size.height);
        UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:targetRect
                                                   byRoundingCorners:UIRectCornerAllCorners
                                                         cornerRadii:CGSizeMake(cornerRadius, cornerRadius)];
        [path setUsesEvenOddFillRule:YES];
        [path addClip];
        CGContextAddPath(context, path.CGPath);
        
        if (backgroundColor && backgroundColor != [UIColor clearColor]) {
            CGContextSetFillColorWithColor(context, backgroundColor.CGColor);
            CGContextFillRect(context, rect);
            CGContextAddPath(context, path.CGPath);
        }
        
        CGContextSetFillColorWithColor(context, [UIColor clearColor].CGColor);
        
        if(borderWidth > 0){
            CGContextSetStrokeColorWithColor(context, borderColor.CGColor);
            CGContextSetLineWidth(context, borderWidth);
            CGContextDrawPath(context, kCGPathFillStroke);
        }else{
            CGContextDrawPath(context, kCGPathFill);
        }
    }
    
    // 阴影设置
    UIColor *shadowColor = (UIColor *)[userInfo valueForKey:LRJ_ShadowColorKey];
    CGFloat shadowBlur = [[userInfo valueForKey:LRJ_ShadowBlurKey] floatValue];
    UIOffset shadowOffset = [[userInfo valueForKey:LRJ_ShadowOffsetKey] UIOffsetValue];
    
    if (shadowColor) {
        CGContextSetShadowWithColor(context, CGSizeMake(shadowOffset.horizontal, shadowOffset.vertical), shadowBlur, shadowColor.CGColor);
    }
    
    UIGraphicsPushContext(context);
    UIImage *image = [userInfo valueForKey:LRJ_BackgroundImageKey];
    [image drawInRect:rect];
    UIGraphicsPopContext();
    
    return YES;
}















@end
